import number from "@/mount/global/number"
import { generateID, isInArray, getDistance, colorful, removeArray } from "@/utils"
import { indexOf } from "lodash"

/* 有关任务系统的基本函数 */
export default class RoomTaskExtension extends Room {
    /* 任务管理器 */
    public MissionManager():void{
        /* 任务初始化管理器 */
        this.InitManager()
        /* 任务冷却管理器 */
        this.CoolDownManager()
        /* 任务超时管理器 */
        this.DelayManager()
        /* 任务绑定更新管理器 */
        this.updateMissonBindData()
        this.updateLabBindData()
        /* ------任务模块挂载区------ */
        // var a = Game.cpu.getUsed()
        /* 被动任务监控 */
        // CREEP
        this.LToS_PAS()
        this.SToNT_PAS()
        this.TToS_PAS()
        this.SToT_PAS()
        this.FTE_PAS()
        this.SToFT_PAS()
        this.FTLE_PAS()
        this.BCT_PAS()
        this.CTL_PAS()
        this.DR_PAS()
        this.DY_PAS()
        // STRUCTURE
        this.SLToCL_PAS()

        /* 主动任务处理 */
        // CREEP
        this.TToT_AC()
        this.SG_AC()
        this.RMH_AC()
        this.OMH_AC()
        this.CIL_AC()
        this.CRW_AC()
        this.BRW_AC()
        this.EHB_AC()
        this.RP_AC()
        this.AIOA_AC()
        this.DSOA_AC()
        // ROOM
        this.FN_AC()
        this.PH_AC()
        this.GP_AC()
        
        // var b = Game.cpu.getUsed()
        
        // console.log(b-a)
    }

    /* 任务挂载 */
    public mountMisson(mis:RoomTask):boolean{
        // 生成唯一ID
        var Index:string
        if (mis.range == 'CREEP') Index = 'C'
        else if (mis.range == 'ROOM') Index = 'R'
        else if (mis.range == 'STRUCTURE') Index = 'S'
        else return
        var tempID = Index + generateID()
        /* 最多允许同时有30个任务，超过则不能再挂载 */
        if (this.memory.Task[mis.range] && this.memory.Task[mis.range].length >= 30)
        {
            // console.log("任务超过上限")
            return false
        }
        /* 如果该任务冷却时间不为0则不允许挂载 */
        if (this.memory.CoolDownDic[mis.Name])
        {
            // console.log("任务挂载冷却中")
            return false
        }
        if (!this.memory.Task[mis.range])
            this.memory.Task[mis.range] = []
        mis.ID = tempID
        if (mis.LabBind)
        {
            for (var l in mis.LabBind)
            {
                if (this.FullBindLab(mis.LabBind[l][0]) || !this.TypeBindLab(mis.LabBind[l][0],mis.LabBind[l][1]))
                {
                    console.log(colorful(`旗帜${l}下实验室绑定数量或资源不对型，绑定失败！任务也挂载失败!`,'red'))
                    return false
                }
            }
        }
        if (!mis.OnlyOne)
        {
            this.memory.Task[mis.range].push(mis)

        }
        else
        {
            /* 只允许1个任务的话，需要先判断是否已经存在任务 */
            for (var lt of this.memory.Task[mis.range])
            {
                if (lt.Name == mis.Name)
                    return false
            }
            /* 不存在任务就挂载任务 */
            this.memory.Task[mis.range].push(mis)
        }
        if (!isInArray(this.memory.IgnoreName,mis.Name))
            console.log(`${mis.Name} 任务挂载√√√ ID:${mis.ID} Room:${this.name}`)
        /* 占用绑定 */
        if (mis.LabBind)
        {
            /* 绑定 this.memory.TaskData.OccupiedLab */
            for (var ll in mis.LabBind)
            {
                if (!this.memory.TaskData.OccupiedLab[mis.LabBind[ll][0]])
                {
                    this.InitBindLab(mis.LabBind[ll][0],mis.LabBind[ll][2],mis.LabBind[ll][1])
                }
                this.BindLab(mis.LabBind[ll][0],tempID,mis.LabBind[ll][1])
            }
        }
        return true
    }

    /* 任务删除 根据ID删除 */
    public deleteMisson_ID(ID:string):boolean{
        var range:TaskRange
        if (ID[0] == 'C') range = 'CREEP'
        else if (ID[0] == 'S') range = 'STRUCTURE'
        else if (ID[0] == 'R') range = 'ROOM'
        else return false
        for (var t of this.memory.Task[range])
        {
            if (t.ID == ID)
            {   
                /* 在冷却链表中加入冷却数据 */
                var coolDownTick = t.cooldownTick
                if (!this.memory.CoolDownDic[t.Name])
                this.memory.CoolDownDic[t.Name] = coolDownTick
                /* 删除lab绑定 */
                if (t.LabBind)
                {
                    for (var l in t.LabBind)
                    {
                        console.log(t.LabBind[l][0],'--',t.ID)
                        this.UnBindLab(t.LabBind[l][0],t.ID)
                    }
                }
                /* 删除任务 */
                var index = this.memory.Task[range].indexOf(t)
                this.memory.Task[range].splice(index,1)
                if (!isInArray(this.memory.IgnoreName,t.Name))
                console.log(`${t.Name} 任务删除××× ID:${t.ID} Room:${this.name}`)
                return true
            }
        }
        console.log(colorful("任务删除失败!",'red'))
        return false
    }

    /* 任务删除 根据名字删除 只允许OnlyOne属性为true的任务 */
    public deleteMisson(role:TaskRange,name:string):boolean{
        for (var i of this.memory.Task[role])
        {
            if (i.Name == name)
            {
                if (!i.OnlyOne) return false
                /* 在冷却链表中加入冷却数据 */
                var coolDownTick = i.cooldownTick
                if (!this.memory.CoolDownDic[i.Name])
                this.memory.CoolDownDic[i.Name] = coolDownTick
                /* 删除任务 */
                /* 删除lab绑定 */
                if (i.LabBind)
                {
                    for (var l in i.LabBind)
                    {
                        console.log(i.LabBind[l][0],'--',i.ID)
                        this.UnBindLab(i.LabBind[l][0],i.ID)
                    }
                }
                var index = this.memory.Task[role].indexOf(i)
                this.memory.Task[role].splice(index,1)
                if (!isInArray(this.memory.IgnoreName,i.Name))
                console.log(`${i.Name} 任务删除××× ID:${i.ID} Room:${this.name}`)
                return true
            }
        }
        return false
    }

    /* 冷却时间管理器 */
    public CoolDownManager():void{
        if (!this.memory.CoolDownDic) this.memory.CoolDownDic = {}
        for (var i in this.memory.CoolDownDic)
        {
            if (this.memory.CoolDownDic[i] > 0)
                this.memory.CoolDownDic[i] -= 1
            else
                delete this.memory.CoolDownDic[i]
        }
    }

    /* 超时管理器 */
    public DelayManager():void{
        for (var key in this.memory.Task)
        {
            for (var i of this.memory.Task[key])
            {
                if (i.isBeHand &&  i.delayTick < 99995)
                    i.delayTick --
                if (i.delayTick <= 0)
                {
                    /* 小于0就删除任务 */
                    this.deleteMisson_ID(i.ID)
                }
            }
        }
    }

    /* 任务初始化模块 */
    public InitManager():void{
        if (!this.memory.TaskMemory) this.memory.TaskMemory = {}
        if (!this.memory.Task) this.memory.Task = {}
        if (!this.memory.IgnoreName) this.memory.IgnoreName = []
        if (!this.memory.zzZ) this.memory.zzZ = false
        if (Game.time % 10) return
        /* 近矿点和远矿点的识别 */
        if (!this.memory.TaskMemory.source1ID || !this.memory.TaskMemory.source2ID)
        {
            var allSource = this.find(FIND_SOURCES)
            var farSource:Source
            if (allSource.length < 1) return
            else if (allSource.length == 1) farSource = allSource[0]
            else
            {
                farSource = allSource[0]
                for (var s of allSource)
                {
                    if (getDistance(s.pos,this.controller.pos) > getDistance(farSource.pos,this.controller.pos))
                    {
                        farSource = s
                    }
                }
            }
            // source1是远矿点
            this.memory.TaskMemory.source1ID = farSource.id
            // source2是近矿点
            if (allSource.length == 1) this.memory.TaskMemory.source2ID = farSource.id
            else
            {
                for (var ss of allSource)
                {
                    if (ss.id != this.memory.TaskMemory.source1ID)
                        this.memory.TaskMemory.source2ID = ss.id
                }
            }
        }
        /* 仓库识别 */
        if (!this.memory.TaskMemory.storageID && this.controller.level >= 4)
        {
            var new_storage = this.find(FIND_MY_STRUCTURES,{filter:{structureType:STRUCTURE_STORAGE }})
            if (new_storage.length == 1) this.memory.TaskMemory.storageID = new_storage[0].id
        }
        /* 近塔识别 */
        if (!this.memory.TaskMemory.NtowerID && this.controller.level >= 3)
        {
            if (!this.memory.center_x) return
            var center = new RoomPosition(this.memory.center_x,this.memory.center_y,this.name)
            var NTower = center.getClosestStructure([STRUCTURE_TOWER],0)
            if (NTower)
            if (getDistance(NTower.pos,center) < 7) this.memory.TaskMemory.NtowerID = NTower.id
        }
        /* 除了近塔外的其他塔识别 */
        if (!this.memory.TaskMemory.OtowerID && this.controller.level >= 5) this.memory.TaskMemory.OtowerID = []
        if (Game.time % 30 == 0 && this.controller.level >= 5)
        {
            this.memory.TaskMemory.OtowerID as string[]
            var ATowers = this.getStructure(STRUCTURE_TOWER) as StructureTower[]
            if (ATowers.length > this.memory.TaskMemory.OtowerID.length + 1)
            {
                for (var t of ATowers) 
                if (this.memory.TaskMemory.NtowerID && t.my && t.id != this.memory.TaskMemory.NtowerID && !isInArray(this.memory.TaskMemory.OtowerID as string[],t.id))
                {
                    var OtowerID = this.memory.TaskMemory.OtowerID as string[]
                    OtowerID.push(t.id)
                }
            }
        }
        /* 终端识别 */
        if (!this.memory.TaskMemory.terminalID && this.controller.level >= 6)
        {
            var Terminal = this.getStructure(STRUCTURE_TERMINAL)
            if (Terminal.length == 1) this.memory.TaskMemory.terminalID = Terminal[0].id
        }
        /* 资源矿识别 */
        if (!this.memory.TaskMemory.mineralID )
        {
            var Mineral_ = this.find(FIND_MINERALS)
            if (Mineral_.length == 1) this.memory.TaskMemory.mineralID = Mineral_[0].id
        }
        /* 提取器识别 */
        if (!this.memory.TaskMemory.extractID && this.controller.level >= 5)
        {
            var extract = this.getStructure(STRUCTURE_EXTRACTOR)
            if (extract.length == 1) this.memory.TaskMemory.extractID = extract[0].id
        }
        /* Link识别 tower_link 需要手动挂载 */
        if (!this.memory.TaskMemory.center_link && this.controller.level >= 5)
        {
            if (!this.memory.center_x) return
            var position_ = new RoomPosition(this.memory.center_x,this.memory.center_y,this.name)
            var center_link = position_.getRangedStructure([STRUCTURE_LINK],3,0) as StructureLink[]
            if (center_link.length >= 1)
            this.memory.TaskMemory.center_link = center_link[0].id
        }
        if (!this.memory.TaskMemory.source_link)
        {
            if (!this.memory.TaskMemory.source1ID) return
            var source1 = Game.getObjectById(this.memory.TaskMemory.source1ID as string) as StructureLink
            if (!source1)
            {
                delete this.memory.TaskMemory.source1ID
                return
            }
            var source_link = source1.pos.getRangedStructure([STRUCTURE_LINK],2,0) as StructureLink[]
            if (source_link.length >= 1)
            this.memory.TaskMemory.source_link = source_link[0].id
        }
        if (!this.memory.TaskMemory.source2_link && this.controller.level >= 7)
        {
            if (!this.memory.TaskMemory.source2ID) return
            var source2 =  Game.getObjectById(this.memory.TaskMemory.source2ID as string) as StructureLink
            if (!source2)
            {
                delete this.memory.TaskMemory.source2ID
                return
            }
            var source2_link = source2.pos.getRangedStructure([STRUCTURE_LINK],2,0) as StructureLink[]
            if (source2_link.length >= 1)
            for (var sl of source2_link)
            {
                if (sl.id != this.memory.TaskMemory.source_link && sl.id != this.memory.TaskMemory.upgrade_link)
                {
                    this.memory.TaskMemory.source2_link = sl.id
                    break
                }
            }
            //this.memory.source2_link = source2_link[0].id
        }
        if (!this.memory.TaskMemory.upgrade_link && this.controller.level >= 6)
        {
            var upgrade_link = this.controller.pos.getRangedStructure([STRUCTURE_LINK],4,0) as StructureLink[]
            if (upgrade_link.length >= 1)
            for (var ul of upgrade_link)
            {
                if (ul.id != this.memory.TaskMemory.source_link && ul.id != this.memory.TaskMemory.source2_link)
                {
                    this.memory.TaskMemory.upgrade_link = ul.id
                    break
                }
            }
        }
        /* 实验室识别 */
        if (Game.time % 50 == 0)
        {
            var ALabs = this.getStructure(STRUCTURE_LAB) as StructureLab[]
            if (ALabs.length > 1)
            {
                if (!this.memory.TaskMemory.labs) this.memory.TaskMemory.labs = []
                for (var llab of ALabs)
                {
                    if (llab.my && !isInArray(this.memory.TaskMemory.labs as string[],llab.id))
                    {
                        var labs = this.memory.TaskMemory.labs as string[]
                        labs.push(llab.id)
                    }
                }
            }
        }
        /* 已经占用的实验室初始化 */
        if(!this.memory.TaskData.OccupiedLab) this.memory.TaskData.OccupiedLab = {}
        /* 核弹识别 */
        if (!this.memory.TaskMemory.NukerID && this.controller.level >= 8 )
        {
            var nuke_ = this.getStructure(STRUCTURE_NUKER)
            if (nuke_.length > 0)
            {
                this.memory.TaskMemory.NukerID = nuke_[0].id
            }
        }
        /* 观察器识别 */
        if (!this.memory.TaskMemory.ObserverID && this.controller.level >= 8 )
        {
            var observer_ = this.getStructure(STRUCTURE_OBSERVER)
            if (observer_.length > 0)
            {
                this.memory.TaskMemory.ObserverID = observer_[0].id
            }
        }
        /* PowerSpawn识别 */
        if (!this.memory.TaskMemory.PowerSpawnID && this.controller.level >= 8)
        {
            var powerSpawn = this.getStructure(STRUCTURE_POWER_SPAWN)
            if (powerSpawn.length > 0)
            this.memory.TaskMemory.PowerSpawnID = powerSpawn[0].id
        }

    }

    /* 任务存在查询模块 */
    public CheckInMisson(range:TaskRange,taskName:string):boolean{
        if (!this.memory.Task[range]) this.memory.Task[range] = []
        for (var t of this.memory.Task[range])
        {
            if (t.Name == taskName)
                return true
        }
        return false
    }

    /* 任务查询模块 ID版本 */
    public CheckInMisson_ID(ID:string):boolean{
        for (var i in this.memory.Task)
            for (var t of this.memory.Task[i])
            {
                if (t.ID == ID)
                    return true
            }
        return false
    }

    /* 同种任务数量查询模块 */
    public CheckMissonNum(range:TaskRange,TaskName:string):number
    {
        if (!this.memory.Task[range]) this.memory.Task[range] = []
        var result:number = 0
        for (var i of this.memory.Task[range])
        {
            if (i.Name == TaskName)
                result += 1
        }
        return result
    }

    /* 获取任务模块 */
    public getMisson(range:TaskRange,taskName:string):RoomTask | null{
        if (!this.memory.Task[range]) this.memory.Task[range] = []
        for (var i of this.memory.Task[range])
        {
            if (i.Name == taskName)
                return i
        }
        return null
    }

    /* 获取任务模块 ID版本 */
    public getMisson_ID(ID:string):RoomTask | null{
        for (var i in this.memory.Task)
            for (var t of this.memory.Task[i])
            {
                if (t.ID == ID)
                    return t
            }
        return null
    }

    /* 任务绑定数据更新模块*/
    public updateMissonBindData():void{
        if (Game.time % 19) return
        for (var ran in this.memory.Task)
        {
            for (var m of this.memory.Task[ran])
            {
                if (ran == 'CREEP' && m.bindData)
                {
                    for (var r in m.bindData)
                    {
                        for (var c of m.bindData[r].bind)
                            if (!Game.creeps[c])
                            {
                                console.log(`删除爬虫${c}的绑定数据！`)
                                var index = m.bindData[r].bind.indexOf(c)
                                m.bindData[r].bind.splice(index,1)
                            }
                    }
                }
            }
        }
    }

    /* 多任务不多工种任务获取模块 */
    public getMisson_S(range:TaskRange,taskName:string,relateCreep:string):RoomTask | null{
        if (!this.memory.Task[range]) this.memory.Task[range] = []
        for (var i of this.memory.Task[range])
        {
            if (i.Name == taskName && isInArray(i.relateCreep,relateCreep))
                return i
        }
        return null
    }

    /* lab绑定数据更新模块 */
    public updateLabBindData():void{
        if (Game.time % 3) return
        for (var i in this.memory.TaskData.OccupiedLab)
        {
            if (this.memory.TaskData.OccupiedLab[i].relate.length <= 0)
                delete this.memory.TaskData.OccupiedLab[i]
            else
            {
                for (var j of this.memory.TaskData.OccupiedLab[i].relate)
                {
                    if (!this.getMisson_ID(j))
                    {
                        removeArray(this.memory.TaskData.OccupiedLab[i].relate,j)
                    }
                }
            }
        }
    }


}